﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection.Emit;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using System.Linq.Expressions;
using UtilZ.Dotnet.Ex.Communication.Net.FastTransfer;
using System.Windows.Markup;

namespace ConAppCore.Test
{
    internal class TestUnsafeAccessor
    {
        public static void Test()
        {
            //TestEmit();
            TestExpression();
        }


        private static void TestExpression()
        {
            // 创建一个表达式树，访问私有成员 _value
            var parameter = Expression.Parameter(typeof(A), "x");

            // 访问私有成员 _value
            //var field = Expression.Field(parameter, typeof(A).GetField("_value", BindingFlags.NonPublic | BindingFlags.Instance));
            var field = Expression.Field(parameter, typeof(A).GetField("_value2", BindingFlags.NonPublic | BindingFlags.Instance));

            // 编译表达式树，生成一个可以访问私有成员 _value 的方法
            var lambda = Expression.Lambda<Func<A, int>>(field, parameter);

            // 调用方法
            var func = lambda.Compile();

            var a = new A();
            var value = func(a);
            Console.WriteLine(value);
        }

        private static void TestEmit()
        {
            // 创建一个动态方法，签名为 int GetValue(A a)
            var method = new DynamicMethod("GetValue", typeof(int), new Type[] { typeof(A) }, typeof(A));

            // 获取方法的 ILGenerator，通过 Emit 生成方法体
            var il = method.GetILGenerator();




            //// 将参数 a 的私有成员 _value 压入堆栈
            //il.Emit(OpCodes.Ldarg_0);

            //// 将私有成员 _value 压入堆栈
            //il.Emit(OpCodes.Ldfld, typeof(A).GetField("_value", BindingFlags.NonPublic | BindingFlags.Instance));

            // 将参数 a 的私有成员 _value 压入堆栈
            il.Emit(OpCodes.Ldarg_0);

            // 将私有成员 _value 压入堆栈
            il.Emit(OpCodes.Ldfld, typeof(A).GetField("_value2", BindingFlags.NonPublic | BindingFlags.Instance));





            // 返回栈顶的值
            il.Emit(OpCodes.Ret);

            // 通过 Emit 创建的方法，可以直接访问私有成员 _value
            var func = (Func<A, int>)method.CreateDelegate(typeof(Func<A, int>));

            // 调用方法
            var a = new A();
            var value = func(a);
            Console.WriteLine(value);
        }
    }

    public class B
    {
        //[UnsafeAccessor(UnsafeAccessorKind.Field, Name = "_value")]
        //static extern ref int GetValue(A a);

        //[UnsafeAccessor(UnsafeAccessorKind.Constructor)]
        //static extern A CreateA(int value);

        //public void TestFieldAndConstructor()
        //{
        //    var a = new A();
        //    ref var value = ref GetValue(a);
        //    Console.WriteLine(value);
        //    value = 20; //因为是引用,所以修改了value=20,也就是a._value修改为了20


        //    var a2 = CreateA(10);
        //    ref var value2 = ref GetValue(a2);
        //    Console.WriteLine(value2);
        //}



        //[UnsafeAccessor(UnsafeAccessorKind.Method, Name = "get_Value")]
        //static extern int GetValue(A a);

        //[UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_Value")]
        //static extern void SetValue(A a, int value);

        //public void TestProperty()
        //{
        //    var a = new A();
        //    SetValue(a, 10);
        //    Console.WriteLine(GetValue(a));
        //}


    }

    public class A
    {
        private int _value = 10;
        private int Value
        {
            get
            {
                return _value;
            }
            set
            {
                _value = value;
            }
        }

        private int _value2 = 100;



        private A(int value)
        {
            this._value = value;
        }

        public A()
        {

        }
    }
}
